#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>


// 借助fork来创建进程
int main()
{
    // printf("我是一个进程,pid:%d,ppid:%d\n",getpid(),getppid());
    // fork();
    // printf("我是一个进程,pid:%d,ppid:%d\n",getpid(), getppid());

    // 借助fork的返回值来使父进程和子进程执行不同的代码逻辑
    // 下面代码有三个问题：
    // 1.fork为什么对父进程和子进程的返回值不同？
    // 2.fork为什么能返回两个值？
    // 3.为什么id变量，即等于0，又大于0，导致else if 和else 同时成立
    
    //1.一个父进程可以有多个子进程，且父进程要对子进程进行管理
    //  如果不给父进程子进程的id，父进程如何区分多个子进程
    //  但是子进程的父进程只有一个，且可以通过ppid获取父进程，所以我们只需要知道那个进程是子进程即可
    
    //2.因为在fork函数内部，在return id之前，就已经创建好了子进程。
    //  而子进程和父进程会共享代码，所以在return的时候就已经开始共享了
    //  子进程和父进程都会进行return返回
    
    //3.每一个进程都是独立的。这里面包含了写时拷贝的问题。
    //  当两个进程共享同一分代码时，一个想要修改代码，此时OS会进行写时拷贝，在内存拷贝一份出来
    //  要修改的进程对拷贝出来的代码进行修改，此时依旧满足进程独立
    printf("我是一个进程，pid:%d,ppid:%d\n",getpid(),getppid());
    pid_t id = fork();
    if(id < 0)
    {
        perror("fork");
        return -1;
    }
    else if(id == 0)
    {
        //child
        while(1)
        {
            sleep(1);
            printf("我是子进程，我的pid:%d, 我的ppid:%d\n",getpid(),getppid());
        }
    }
    else
    {
        // father
        while(1)
        {
            sleep(1);
            printf("我是父进程，我的pid:%d,我的ppid:%d\n",getpid(),getppid());
        }
    }
    return 0;
}


// OS会给每一个用户一个bash进程
// bash就是命令行解释器

int main1()
{
    // ./proc 以文件的形式查看进程
    // 所有的数字目录都是进程
    // 进入当前进程的目录中后，有两个特殊的文件
    // exe 和cwd
    // exe 指的是当前进程所依赖的二进制文件所处的位置
    // cwd 指的是二进制文件所在的目录
    // fopen会默认在当前目录下创建文件
    // 我们可以修改进程中的cwd文件—chdir
    // 这样fopen就会将文件新建到修改后的目录下
    fopen("process1.txt1","w");
    chdir("/home/xsc");
    fopen("process2.txt","w");

    while(1)
    {
        sleep(1);
        printf("我是一个进程，pid: %d , ppid: %d \n",getpid(),getppid());
    }

    return 0;
}
